package org.starsource.forum.server.dao.test;

import static org.junit.Assert.*;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import org.starsource.forum.client.exception.DataNotFoundException;
import org.starsource.forum.client.exception.DatabaseException;
import org.starsource.forum.server.dao.CategoryDao;
import org.starsource.forum.server.domain.Category;

public abstract class AbsTestCategoryDao {

	protected static org.apache.log4j.Logger logger = org.apache.log4j.LogManager
	.getLogger(AbsTestCategoryDao.class.getName());
	
	@Autowired
	private CategoryDao categoryDao;
	
//	@Override
//	protected String[] getConfigLocations() {
//		return new String[] {"forum-dao-hibernate.xml", "starforum-transaction.xml"};
//	}

	@Test
	public void testSave() throws DatabaseException {
		Category category1 = new Category(null, "NAME_FOR_UNIT_TEST", "CAPTION_FOR_UNIT_TEST");
		categoryDao.save(category1);
		
		Category category2 = categoryDao.getCategory(category1.getId());
		assertEquals(category1, category2);
		
		Category category3 = new Category(category1, "NAME3_FOR_UNIT_TEST", "CAPTION3_FOR_UNIT_TEST");
		category1.getChildren().add(category3);
		categoryDao.save(category3);
		
		Category category4 = categoryDao.getCategory(category3.getId());
		assertEquals(category3, category4);

		Category category5 = new Category(null, null, null);
		categoryDao.save(category5);

		Category category6 = categoryDao.getCategory(category5.getId());
		assertEquals(category5, category6);
	}

	@Test
	public void testUpdate() throws DatabaseException {
		Category category1 = new Category(null, "NAME_FOR_UNIT_TEST", "CAPTION_FOR_UNIT_TEST");
		Category category2 = new Category(category1, "NAME2_FOR_UNIT_TEST", "CAPTION2_FOR_UNIT_TEST");
		Category category3 = new Category(category2, "NAME3_FOR_UNIT_TEST", "CAPTION3_FOR_UNIT_TEST");
		Category category4 = new Category(null, "NAME4_FOR_UNIT_TEST", "CAPTION4_FOR_UNIT_TEST");
		Category category5 = new Category(null, "NAME5_FOR_UNIT_TEST", "CAPTION5_FOR_UNIT_TEST");
		Category category6 = new Category(null, "NAME5_FOR_UNIT_TEST", "CAPTION5_FOR_UNIT_TEST");

		category1.getChildren().add(category2);
		category2.getChildren().add(category3);

		categoryDao.save(category1);
		categoryDao.save(category2);
		categoryDao.save(category3);
		categoryDao.save(category4);
		categoryDao.save(category5);
		categoryDao.save(category6);

		category2.setName("CATEGORY_NAME_NEW");
		category2.setCaption("CATEGORY_CAPTION_NEW");
		category2.setParent(category4);
		category4.getChildren().add(category2);
		category2.getChildren().remove(category3);
		category3.setParent(null);
		category2.getChildren().add(category5);
		category5.setParent(category2);
		category6.setCaption(null);
		category6.setName(null);
		category6.setParent(null);
		categoryDao.update(category2);
		categoryDao.update(category3);
		categoryDao.update(category4);
		categoryDao.update(category5);
		categoryDao.update(category6);

		assertEquals(category2, categoryDao.getCategory(category2.getId()));
		
		assertEquals(category3, categoryDao.getCategory(category3.getId()));
		
		assertEquals(category4, categoryDao.getCategory(category4.getId()));
		assertEquals(category5, categoryDao.getCategory(category5.getId()));
		assertEquals(category6, categoryDao.getCategory(category6.getId()));
		
	}

	@Test
	public void testDelete() throws DatabaseException {
		Category category1 = new Category(null, "NAME_FOR_UNIT_TEST", "CAPTION_FOR_UNIT_TEST");
		categoryDao.save(category1);
		
		Category category2 = new Category(category1, "NAME3_FOR_UNIT_TEST", "CAPTION3_FOR_UNIT_TEST");
		category1.getChildren().add(category2);
		categoryDao.save(category2);
		
		int categoryId = category2.getId();
		categoryDao.delete(category2);
		try {
			categoryDao.getCategory(categoryId);
			assertTrue(false);
		} catch (DataNotFoundException e) {
		}
	}

	@Test
	public void testGetCategory() throws DatabaseException {
		Category category1 = new Category(null, "NAME_FOR_UNIT_TEST", "CAPTION_FOR_UNIT_TEST");
		categoryDao.save(category1);
		
		Category category2 = categoryDao.getCategory(category1.getId());
		assertEquals(category1, category2);
		
		Category category3 = new Category(category1, "NAME3_FOR_UNIT_TEST", "CAPTION3_FOR_UNIT_TEST");
		category1.getChildren().add(category3);
		categoryDao.save(category3);
		
		Category category4 = categoryDao.getCategory(category3.getId());
		assertEquals(category3, category4);

		Category category5 = new Category(null, null, null);
		categoryDao.save(category5);
		
		Category category6 = categoryDao.getCategory(category5.getId());
		assertEquals(category5, category6);
	}
	
	@Test
	public void testGetCategoryList() throws DatabaseException {
		Set<Category> rootCategorySet = new LinkedHashSet<Category>();
		for(int j=0; j<10; j++) {
			Category category = new Category(null, "ROOT_NAME_" + j + "_FOR_UNIT_TEST", "ROOT_CAPTION_+" + j + "_FOR_UNIT_TEST");
			categoryDao.save(category);
			for(int k=0; k<5; k++) {
				Category subCategory = new Category(category, "SUB_NAME_" + j + "_" + k + "_FOR_UNIT_TEST", "SUB_CAPTION_+" + j + "_" + k + "_FOR_UNIT_TEST");
				category.getChildren().add(subCategory);
				categoryDao.save(subCategory);
			}
		}
		
		Set<Category> checkCategorySet = categoryDao.getCategorySet();
		assertTrue(checkCategorySet.containsAll(rootCategorySet));
		Iterator<Category> iterator = checkCategorySet.iterator();
		while (iterator.hasNext()) {
			Category category = iterator.next();
			if (rootCategorySet.contains(category)) {
				assertTrue(category.getChildren().size() == 5);
			}
		}
		
	}

}
